﻿#include "examdialog.h"
#include <QDebug>
#include <QString>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QStringList>
#include <QPushButton>
#include <QChar>
#include <QApplication>

typedef  enum  class Item_State
{
    BEGIN,          //开始读题目
    READ_QUESTION,  //开始读选项
    READ_ITEM,      //读选项
    READ_ASWER      //读取答案
}Item_State;

ExamDialog::ExamDialog(QWidget*parent):QDialog(parent),m_items_per_line(10)
{
    QFont font;
    font.setPointSize(12);
    this->setFont(font);

    setPalette(QPalette(QColor(109,215,255)));

    resize(800,900);

    setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint|Qt::WindowMinMaxButtonsHint);

    setWindowTitle("考试已用时: 0分0秒");
    initTimer();
    initLayout();
    if(!initTextEdit())
    {
        QTimer::singleShot(0,qApp,SLOT(quit()));//退出
        return;
    }
    initButtons();

    show();

}

ExamDialog::~ExamDialog()
{
    m_timer->stop();
    delete m_timer;
}

void ExamDialog::initTimer()
{
    m_timeGo=0;
    m_timer = new QTimer(this);
    m_timer->setInterval(1000);
    connect(m_timer,SIGNAL(timeout()),this,SLOT(updateTime()));
    m_timer->start();
}

void ExamDialog::initLayout()
{
    m_layout = new QGridLayout(this);
    m_layout->setMargin(10);
    m_layout->setSpacing(10);
}

bool ExamDialog::initTextEdit()
{

    QString fileName("../exam.txt");
    QFile file(fileName);

    QTextStream textStream(&file);
    textStream.setCodec("UTF-8");

    QString strLine;
    QString strText;
    bool isFirstReq=true;
    Item_State is=Item_State::BEGIN;

    QString qLabel;//标签
    QStringList items;//选项
    QStringList answers;//答案

    bool needRead =true;


    if(file.open(QIODevice::ReadOnly|QIODevice::Text))
    {
        m_textEdit=new QTextEdit();
        m_textEdit->setReadOnly(true);

        while(1)
        {
            if(needRead)
            {
                if(textStream.atEnd())
                {
                    break;
                }

                strLine=textStream.readLine();
                qDebug()<<"read line: "<<strLine<<endl;

                strLine=strLine.trimmed();

                if(strLine.length()<1)continue;

                if(strLine.at(0)=="#")continue;
            }
            else
            {
                needRead=true;
            }

            //状态机
            switch (is) {
            case Item_State::BEGIN://读题目
                items.clear();//为了读新的选项
                answers.clear();

                if(strLine.at(0)=='Q')
                {
                    needRead=false;
                    is=Item_State::READ_QUESTION;
                }
                else//格式错误
                {
                    QMessageBox::information(this,"提示","题目格式不是Q有问题");
                }
                break;
            case Item_State::READ_QUESTION://读选项
                if(strLine.at(0)=='Q')
                {
                    qDebug()<<"取得题目行:"<<strLine<<endl;

                    if(isFirstReq)
                    {

                        isFirstReq=false;
                    }
                    else
                    {
                        strText.append('\n');
                    }
                    qLabel=strLine.remove(0,1);//删除标记符
                    int pos=strLine.indexOf(".");//题目号后面有一个.

                    if(pos>0)
                    {
                        qLabel.resize(pos);//会截断在.号的位置
                        qDebug()<<"题目标签: "<<qLabel<<endl;
                    }

                    strText.append(strLine);
                    strText.append('\n');
                    is=Item_State::READ_ITEM;
                }
                else//格式错误
                {
                    QMessageBox::information(this,"提示","题目格式不是Q有问题");
                }
                break;
            case Item_State::READ_ITEM://变量不能直接定义在case下面

                if(strLine.at(0)=='.')
                {
                    QString label;
                    QString item=strLine.remove(0,1);
                    int pos=item.indexOf(" ");//选项后面有一个空格
                    if(pos>0)
                    {

                        for(int i=0;i<pos;i++)
                        {
                            label.append(item[i]);//添加abcd
                        }
                    }
                    else
                    {
                        label=item;//这个放正确和错误,放整个
                    }

                    qDebug()<<"获取到选项:"<<label<<endl;
                    items.append(label);

                    strText.append(strLine);
                    strText.append('\n');
                    //is=Item_State::READ_ITEM;
                }
                else if(strLine.at(0)=="!")//选项已读完,读到答案了
                {
                    is=Item_State::READ_ASWER;
                    needRead=false;

                }
                else//如选项中多有一些其他的一行.
                {
                    //警告
                    is=Item_State::READ_ASWER;//就是异常也要去读答案
                }
                break;
            case Item_State::READ_ASWER:
                if(strLine.at(0)=='!')
                {
                    if(items.size()<1)//异常,没有选项,直接读到答案
                    {
                        //答案前没有选项
                        QMessageBox::information(this,"错误","请设置好选项,题目"+qLabel);
                        break;
                    }


                //读取答案...
                if(('a'<=strLine[1]&&'z'>=strLine[1])||('A'<=strLine[1]&&'Z'>=strLine[1]))
                {
                    for(int i=1;i<strLine.size();i++)
                    {
                        answers.append(QString(strLine[i]));
                        qDebug()<<"获取到答案:"<<answers.back();
                    }
                }
                else//非字母选项
                {
                    answers.append(strLine.remove(0,1));
                    qDebug()<<"获取到答案:"<<answers.back();
                }


                if(answers.size()<1)
                {
                    QMessageBox::information(this,"错误","答案为空,请设置好答案,题目"+qLabel);
                }
                else
                {
                    answeritem *ai=new answeritem(qLabel,answers);
                    for(int i=0;i<items.size();i++)
                    {
                        ai->add_item(items[i]);
                    }

                    m_items.append(ai);//添加到vector会拷贝
                }

                    is=Item_State::BEGIN;//读取完答案就该读新的题了
                }
                else
                {
                    QMessageBox::information(this,"错误","答案为空,请设置好答案,题目"+qLabel);
                    return false;
                }
                break;
            default:
                break;
            }
        }

        qDebug()<<"题目数量:"<<m_items.size()<<endl;

        m_textEdit->setText(strText);
        m_layout->addWidget(m_textEdit,0,0,1,10);
        file.close();

        return true;
    }
    else
    {
        QMessageBox::information(this,"提示","读取文件失败!");
        return false;
    }
}

void ExamDialog::initButtons()
{
    unsigned lineNo=1,maxItemNum=0;

    for(int i=0;i<m_items.size();i++)
    {
        if(i%m_items_per_line==0&&i!=0)
        {
            lineNo+=maxItemNum+2;
            maxItemNum=0;
        }
        //1.生成标签
        QLabel*label=new QLabel(this);
        label->setText("第" + m_items[i]->get_label()+"题");
        qDebug()<<m_items[i]->get_num()<<endl;
        if(m_items[i]->get_num()>maxItemNum)
        {
            maxItemNum=m_items[i]->get_num();
        }

        m_layout->addWidget(label,lineNo,i%m_items_per_line);

        QVector<QPair<QString,int>>&item_name=m_items[i]->get_items();

        //2.生成选项 单选/多选  选项
        QButtonGroup*qbg=new QButtonGroup(this);
        if(m_items[i]->is_single_type())
        {


            for(unsigned j=0;j<m_items[i]->get_num();j++)
            {

                QRadioButton*qb=new QRadioButton(this);
                qb->setText(item_name[j].first);
                qbg->addButton(qb);
                m_layout->addWidget(qb,lineNo+1+j,i%m_items_per_line);

                //m_checkBtns.append(qb);
            }
        }
        else//多选
        {
            qbg->setExclusive(false);//多选组
            for(unsigned j=0;j<m_items[i]->get_num();j++)
            {
                QCheckBox*qcb=new QCheckBox(this);
                qcb->setText(item_name[j].first);
                m_layout->addWidget(qcb,lineNo+1+j,i%m_items_per_line);
                //m_checkBtns.append(qcb);
                qbg->addButton(qcb);
            }
        }

        m_btnGroups.append(qbg);
    }


    //生成提交按钮
    QPushButton *submiBtn=new QPushButton(this);
    submiBtn->setText("提交");
    submiBtn->setFixedSize(100,35);
    connect(submiBtn,SIGNAL(clicked(bool)),this,SLOT(getScore()));
    m_layout->addWidget(submiBtn,lineNo+maxItemNum+1,m_items_per_line-1);

}

void ExamDialog::updateTime()
{
    QString title;
    m_timeGo++;

    setWindowTitle("考试已用时: "+QString::number(m_timeGo/60)+"分"+QString::number(m_timeGo%60)+"秒");
}

void ExamDialog::getScore()
{
    int totalScore=0;
    //检测是否选完
    for(int i=0;i<m_items.size();i++)
    {
        if(!m_btnGroups[i]->checkedButton())
        {
            QMessageBox::information(this,"温馨提示","您还有选题未答,请继续答题");
            return;
        }
        if(m_items[i]->is_single_type())//单选
        {
            qDebug()<<m_btnGroups[i]->checkedButton()->text();
            qDebug()<<m_items[i]->get_ansmers()[0];
            if(m_btnGroups[i]->checkedButton()->text()==m_items[i]->get_ansmers()[0])
            {
                totalScore+=10;
            }
        }
        else//多选
        {
            QList<QAbstractButton*>button=m_btnGroups[i]->buttons();
            const QStringList& list=m_items[i]->get_ansmers();
            int selectedNum=0,validNum=0;
            for(int i=0;i<button.size();i++)
            {
                int j=0;
                if(button[i]->isChecked())
                {
                    selectedNum++;

                    for(j=0;j<list.size();j++)
                    {
                        if(list[j]==button[i]->text())
                        {
                            break;
                        }
                    }

                    if(j==list.size())
                    {
                        break;
                    }
                    validNum++;
                }
            }

            if(selectedNum==validNum&&validNum==list.size())
            {
                totalScore+=10;
            }

        }
    }


    int res= QMessageBox::information(this,"总分","您的总分是:"+QString::number(totalScore)+"分,是否重新考试?",QMessageBox::Yes|QMessageBox::No);
    if(res==QMessageBox::Yes)
    {
        return;
    }
    else
    {
        close();
    }
}
